package com.flower.web.controller.business;


import cn.hutool.core.lang.Snowflake;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.flower.common.config.RuoYiConfig;
import com.flower.common.core.controller.BaseController;
import com.flower.common.core.domain.AjaxResult;
import com.flower.common.utils.file.FileUploadUtils;
import com.flower.framework.web.service.TokenService;
import com.flower.system.domain.BizRecognition;
import com.flower.system.domain.BizWiki;
import com.flower.system.domain.dto.BaikeInfo;
import com.flower.system.domain.dto.PlantMatch;
import com.flower.system.domain.dto.PlantRecognitionResult;
import com.flower.system.service.IBizRecognitionService;
import com.flower.system.service.IBizWikiService;
import com.flower.system.service.ISysUserService;
import okhttp3.*;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.Date;
import java.util.List;

/**
 * 需要添加依赖
 * <!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
 * <dependency>
 *     <groupId>com.squareup.okhttp3</groupId>
 *     <artifactId>okhttp</artifactId>
 *     <version>4.12.0</version>
 * </dependency>
 */
@RestController
public class FlowerController extends BaseController {
    //aI7ioGvKZLf17Nn2JvnvHIma

    public static final String API_KEY = "aI7ioGvKZLf17Nn2JvnvHIma";
    //ahJPuQpLxcRLstKn6EwD7cYzk9Wi1xBw
    public static final String SECRET_KEY = "ahJPuQpLxcRLstKn6EwD7cYzk9Wi1xBw";

    static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();


    @Autowired
    private ISysUserService userService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private IBizRecognitionService recognitionService;

    @Autowired
    private IBizWikiService wikiService;


    @PostMapping("/flowerImage")
    public AjaxResult flowerImage(@RequestParam("file") MultipartFile file) throws Exception
    {

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        if (!file.isEmpty())
        {
            //上传到系统
            // 上传文件路径
            String filePath = RuoYiConfig.getUploadPath();
            // 上传并返回新文件名称
            String fileName = FileUploadUtils.upload(filePath, file);

            String base64 = convertMultipartFileToBase64(file);

            base64 = URLEncoder.encode(base64, "utf-8");

            RequestBody body = RequestBody.create(mediaType, "baike_num=1&image="+base64);
            Request request = new Request.Builder()
                    .url("https://aip.baidubce.com/rest/2.0/image-classify/v1/plant?access_token=" + getAccessToken())
                    .method("POST", body)
                    .addHeader("Content-Type", "application/x-www-form-urlencoded")
                    .addHeader("Accept", "application/json")
                    .build();
            Response response = HTTP_CLIENT.newCall(request).execute();
            String jsonResult = response.body().string();
            System.out.println(jsonResult);


            /**
             *
             * {"result":
             * [{"score":0.5783837,"name":"樟",
             * "baike_info":
             * {"baike_url":"https://baike.baidu.com/item/%E6%A8%9F/2506377",
             * "image_url":"https://bkimg.cdn.bcebos.com/pic/37d12f2eb9389b500147f2078a35e5dde7116e2e?x-bce-process=image/resize,m_lfit,w_536,limit_1/quality,Q_70",
             * "description":"樟（学名：Camphora officinarum Nees ex Wall）是樟科、樟属常绿大乔木，常绿大乔木，树冠广卵形；枝、叶及木材均有樟脑气味"}
             * },
             * {"score":0.4609468,"name":"榕树"},{"score":0.039955683,"name":"垂叶榕"}],"log_id":1775518378586993157}
             */

            //ObjectMapper mapper = new ObjectMapper();
            //PlantRecognitionResult recognitionResult = mapper.readValue(jsonResult, PlantRecognitionResult.class);

            // 先解析顶层对象
            JSONObject jsonObject = JSON.parseObject(jsonResult);

            // 获取result数组并解析为PlantMatch列表
            List<PlantMatch> matchList = JSON.parseArray(jsonObject.getJSONArray("result").toJSONString(), PlantMatch.class);

            // 获取其他属性
            long logId = jsonObject.getLongValue("log_id");

            // 构建PlantRecognitionResult对象
            PlantRecognitionResult recognitionResult = new PlantRecognitionResult();
            recognitionResult.setResult(matchList);
            recognitionResult.setLogId(logId);

            List<PlantMatch> recognitionResultResult = recognitionResult.getResult();
            if(recognitionResultResult.size()==3){
                //最相似
                PlantMatch plantMatch1 = recognitionResultResult.get(0);
                String name = plantMatch1.getName();
                double score = plantMatch1.getScore();

                //取到百科
                BaikeInfo baikeInfo = plantMatch1.getBaikeInfo();
                String baikeUrl = baikeInfo.getBaikeUrl();
                String imageUrl = baikeInfo.getImageUrl();
                String description = baikeInfo.getDescription();


                //第二
                PlantMatch plantMatch2 = recognitionResultResult.get(0);
                double score2 = plantMatch2.getScore();
                String name2 = plantMatch2.getName();


                //第三
                PlantMatch plantMatch3 = recognitionResultResult.get(0);
                double score3 = plantMatch3.getScore();
                String name3 = plantMatch3.getName();

                Snowflake snowflake = new Snowflake(1, 1);
                //1.入鉴定记录表
                BizRecognition bizRecognition = new BizRecognition();
                String recognitionId = snowflake.nextIdStr();
                bizRecognition.setOriginalImageUrl(fileName);
                bizRecognition.setId(recognitionId);
                //百科相关
                bizRecognition.setDescription(description);
                bizRecognition.setImageUrl(imageUrl);
                bizRecognition.setBaikeUrl(baikeUrl);
                //植物名称
                bizRecognition.setName1(name);
                bizRecognition.setName2(name2);
                bizRecognition.setName3(name3);
                //植物相似度
                bizRecognition.setScore1(String.valueOf(score));
                bizRecognition.setScore2(String.valueOf(score2));
                bizRecognition.setScore3(String.valueOf(score3));
                bizRecognition.setCreateTime(new Date());
                //入库
                recognitionService.insertBizRecognition(bizRecognition);

                //2.入植物百科表
                BizWiki bizWiki = new BizWiki();
                bizWiki.setId(snowflake.nextIdStr());
                bizWiki.setName(name);
                bizWiki.setImageUrl(imageUrl);
                bizWiki.setBaikeUrl(baikeUrl);
                bizWiki.setDescription(description);
                bizWiki.setCreteTime(new Date());
                
                //入库
                wikiService.insertBizWiki(bizWiki);


                //3.将植物鉴定表的实体返回给前端
                return  AjaxResult.success(bizRecognition);

            }else{
                //入记录表
                //最相似
                PlantMatch plantMatch1 = recognitionResultResult.get(0);
                String name = plantMatch1.getName();
                double score = plantMatch1.getScore();
                String nextIdStr = new Snowflake(1, 1).nextIdStr();
                BizRecognition bizRecognition = new BizRecognition();
                bizRecognition.setCreateTime(new Date());
                bizRecognition.setId(nextIdStr);
                bizRecognition.setOriginalImageUrl(fileName);
                bizRecognition.setScore1(String.valueOf(score));
                bizRecognition.setName1(name);
                recognitionService.insertBizRecognition(bizRecognition);
                return error("未能识别出花卉，请重新上传");
            }
        }
        return error("上传过程中发生错误");
    }

    public String convertMultipartFileToBase64(MultipartFile multipartFile) throws IOException {
        // 获取MultipartFile的输入流
        InputStream inputStream = multipartFile.getInputStream();

        // 创建一个ByteArrayOutputStream来存储读取到的字节数据
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        // 将输入流中的数据写入到输出流中
        byte[] buffer = new byte[1024];
        int read;
        while ((read = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, read);
        }

        // 关闭输入流
        inputStream.close();

        // 获取已写入数据的字节数组
        byte[] bytes = outputStream.toByteArray();

        // 使用Base64工具类对字节数组进行编码，得到Base64字符串

        return Base64.getEncoder().encodeToString(bytes);
    }

    public static void main(String[] args) throws IOException {
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        // image 可以通过 getFileContentAsBase64("C:\fakepath\2018-05-16_OakTreeMaize_EN-AU10918567606_1920x1080.jpg") 方法获取,如果Content-Type是application/x-www-form-urlencoded时,第二个参数传true
        RequestBody body = RequestBody.create(mediaType, "image=%2F9j%2F4AAQSkZJRgABAQEAAAAAAAD%2F2wBDABENDQ0ODRIODhIaEQ8RGh8XEhIXHyIXFxcXFyIjGx4dHR4bIyMpKi0qKSM2Nj...");
        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/rest/2.0/image-classify/v1/plant?access_token=" + getAccessToken())
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .addHeader("Accept", "application/json")
                .build();
        Response response = HTTP_CLIENT.newCall(request).execute();
        System.out.println(response.body().string());

    }

    /**
     * 获取文件base64编码
     *
     * @param path      文件路径
     * @param urlEncode 如果Content-Type是application/x-www-form-urlencoded时,传true
     * @return base64编码信息，不带文件头
     * @throws IOException IO异常
     */
    static String getFileContentAsBase64(String path, boolean urlEncode) throws IOException {
        byte[] b = Files.readAllBytes(Paths.get(path));
        String base64 = Base64.getEncoder().encodeToString(b);
        if (urlEncode) {
            base64 = URLEncoder.encode(base64, "utf-8");
        }
        return base64;
    }


    /**
     * 从用户的AK，SK生成鉴权签名（Access Token）
     *
     * @return 鉴权签名（Access Token）
     * @throws IOException IO异常
     */
    static String getAccessToken() throws IOException {
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "grant_type=client_credentials&client_id=" + API_KEY
                + "&client_secret=" + SECRET_KEY);
        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/oauth/2.0/token")
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .build();
        Response response = HTTP_CLIENT.newCall(request).execute();
        String bodyString = response.body().string();
        JSONObject jsonObject = JSON.parseObject(bodyString);
        return jsonObject.getString("access_token");

    }
}
